//
// Created by Administrator on 2018/7/1 0001.
//

#include "WIQueue.h"

int WIQueue::putAvPacket(AVPacket *avPacket) {
    //加锁
    pthread_mutex_lock(&mutexpacket);
    //入队
    queuepacket.push(avPacket);

    if (DEBUG) {
        LOGI("加入一个packet到队列,队列中的个数为:%d", queuepacket.size());
    }

    //通知消费者
    pthread_cond_signal(&condpacket);
    //解锁
    pthread_mutex_unlock(&mutexpacket);
    return 0;
}

int WIQueue::getAvPacket(AVPacket *avPacket) {
    //加锁
    pthread_mutex_lock(&mutexpacket);
    //根据播放状态判断是否出队
    while (playState != NULL && !playState->exit) {
        if (queuepacket.size() > 0) {

            AVPacket *pkt = queuepacket.front();
            //将pkt中的数据指针赋值给avPacket，注意这里不是将数据复制给去 只是指针之间的赋值
            if (av_packet_ref(avPacket, pkt) == 0) {
                queuepacket.pop();
            }
            //释放队列中的akt 队列中的内存（指针）会释放 但是akt中指针指向的数据不会被释放，因为还有指针指向它
            av_packet_free(&pkt);
            av_free(pkt);
            pkt = NULL;
            if (DEBUG) {
                LOGI("从packet队列中取出一个packet,队列中剩余为%d", queuepacket.size());
            }
            break;
        } else {
            //等待
            pthread_cond_wait(&condpacket, &mutexpacket);
        }
    }
    //解锁
    pthread_mutex_unlock(&mutexpacket);
    return 0;
}

WIQueue::WIQueue(WIPlayState *playState) {
    //初始化线程锁和消息
    pthread_mutex_init(&mutexpacket, NULL);
    pthread_cond_init(&condpacket, NULL);
    this->playState = playState;
}

WIQueue::~WIQueue() {

    clearPackets();
    //析构函数 释放线程锁和消息
    pthread_mutex_destroy(&mutexpacket);
    pthread_cond_destroy(&condpacket);


}

int WIQueue::getQueueSize() {
    int size = 0;
    //获取队列大小 注意这里是多线程 需要加锁
    pthread_mutex_lock(&mutexpacket);
    size = queuepacket.size();
    pthread_mutex_unlock(&mutexpacket);
    return size;
}

void WIQueue::clearPackets() {

    pthread_cond_signal(&condpacket);
    pthread_mutex_lock(&mutexpacket);

    while (!queuepacket.empty()) {
        AVPacket *avPacket = queuepacket.front();
        queuepacket.pop();
        av_packet_free(&avPacket);
        av_free(avPacket);
        avPacket = NULL;
    }


    pthread_mutex_unlock(&mutexpacket);

}

